<template>
    <Window :title="'编辑器'" :show="props.isShow" @cancel="changeCancel" @ok="changeOk" :width="800" :height="500">
        <div style="margin-left:10px">
            <button @click="copyJson">复制</button>
            <button @click="importJsonFile">导入</button>
            <button @click="exportJsonFile">导出</button>
        </div>
        <iframe :src="iframeSrc" frameborder="0" @load="loadIframe" ref="mainIframe"
            style="width:100%;  height:calc(100% - 50px);cursor: not-allowed"></iframe>
    </Window>
</template>

<script setup lang="ts">
import { ref ,inject} from "vue";
import { getOpenFileHandle, getSaveFileHandle, getTextFromFile, saveFile } from 'xbsj-xe2/dist-node/xe2-base-objects';
import { Message } from "earthsdk-ui"
import Window from "../../../components/commom/Window.vue";
import { SceneObject } from "xbsj-xe2/dist-node/xe2-utils";
import { XbsjEarthUi } from '../../../scripts/xbsjEarthUi';
import {createSceneObjTreeItemFromJson} from "../../../pages/plotting/esObj/fun"

const emits = defineEmits(["changeShow"]);
const xbsjEarthUi = inject('xbsjEarthUi') as XbsjEarthUi;

const mainIframe = ref<HTMLIFrameElement>();

const props = withDefaults(defineProps<{
    isShow: boolean,
}>(), {});
const getAssetsDir = () => {
    return SceneObject.context.getEnv(`vue-xe2-plugin-assets-dir`);
}
const copyClipboard = async (text: string) => {//复制
    navigator.clipboard.writeText(text)
        .then(function () {
            Message.success('复制成功');
        }, function (e) {
            Message.error(`复制失败!error:${e}`);
        });
}
const iframeSrc = getAssetsDir() + '/monaco-editor/json-editor.html';
const loadIframe = async () => {
    await setJson('{}')
}
const changeOk = async () => {
    const str = await getJson()
    try {
        const json = JSON.parse(str);
        if (json) {
           createSceneObjTreeItemFromJson(xbsjEarthUi,json)
        }
        changeCancel()
    } catch (error) {
        console.log('JSON格式错误!!!', error);
        Message.error( `JSON格式错误！ error: ${error}`);
        return
    }
}
const changeCancel = () => {
    emits("changeShow", false);
}

const copyJson = async () => {
    const str = await getJson()
    copyClipboard(str)//复制
}

const importSetJson = async (str: string) => {
    await setJson(str)
}

const importJsonFile = async () => { //导入文件
    try {
        Message.warning('正在打开..')
        const handle = await getOpenFileHandle('json');
        if (!handle) return;
        const jsonStr = await getTextFromFile(handle);
        if (!jsonStr) return;
        importSetJson(jsonStr)
        Message.success('导入成功！')
    } catch (error) {
        Message.error(`打开失败！ error: ${error}`);
    }
}
const exportJsonFile = async () => {
    const str = await getJson()
    saveAs(str)
}
const saveAs = async (jsonStr: string, name?: string) => {
    try {
        Message.warning('正在另存为..');
        const handle = await getSaveFileHandle('json', name);
        if (!handle) return;
        await saveFile(handle, jsonStr);
        Message.success('另存成功!');
    } catch (error) {
        Message.error(`另存失败! error: ${error}`);
    }
}

function getUuid() {
    var d = new Date().getTime();
    if (window.performance && typeof window.performance.now === "function") {
        d += performance.now();
    }
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
        var r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
    return uuid;
}

function setJson(value: string) {
    return new Promise<void>((resolve, reject) => {
        if (!mainIframe.value || !mainIframe.value.contentWindow) {
            return;
        }
        const setKey = getUuid()
        mainIframe.value.contentWindow.postMessage({ type: 'setJson', id: setKey, value })
        const time = setTimeout(() => {
            removeEventListener('message', messageSetEventWatch, false);
            reject();
        }, 10000);

        const messageSetEventWatch = (messageEvent: MessageEvent<{ type: string, id: string, status: string } | undefined>) => {
            var data = messageEvent.data;
            if (!data || (data.type && data.type !== 'setJsonReturn') || (data.id && data.id !== setKey)) {
                return;
            }
            removeEventListener('message', messageSetEventWatch, false);
            clearTimeout(time)
            if (data.status === 'ok') {
                resolve();
            } else {
                reject();
            }
        }
        addEventListener('message', messageSetEventWatch, false);
    })

}

function getJson() {
    return new Promise<string>((resolve, reject) => {
        if (!mainIframe.value || !mainIframe.value.contentWindow) {
            return;
        }
        const getKey = getUuid()
        mainIframe.value.contentWindow.postMessage({ type: 'getJson', id: getKey })
        const time = setTimeout(() => {
            removeEventListener('message', messageGetEventWatch, false);
            reject();
        }, 10000);

        const messageGetEventWatch = (messageEvent: MessageEvent<{ type: string, id: string, status: string, value: string | undefined } | undefined>) => {
            var data = messageEvent.data;
            if (!data || (data.type && data.type !== 'getJsonReturn') || (data.id && data.id !== getKey)) {
                return;
            }
            removeEventListener('message', messageGetEventWatch, false);
            clearTimeout(time)
            if (data.status === 'ok' && data.value) {
                resolve(data.value);
            } else {
                reject();
            }
        }
        addEventListener('message', messageGetEventWatch, false);
    })

}


</script>
<style scoped>
button {
    width: 80px;
    height: 32px;
    background: rgba(28, 28, 29, 0.60);
    border-radius: 4px;
    border: 1px solid rgba(28, 28, 29, 0.60);
    cursor: pointer;
    color: rgba(230, 230, 230, 1);
    margin-left: 20px;
    margin-top: 10px;
}

button:hover {
    border: 1px solid #2c68f7;
}

.readonly_true {
    cursor: no-drop;
    background-color: #4c4c4c;
}
</style>